import type { RouteRecordRaw } from 'vue-router';
import { h, resolveComponent as _resolve } from 'vue';

type MenuNode = {
  menuId: number;
  menuName: string;
  path?: string;
  component?: string;
  parentId?: number;
  sort?: number;
  children?: MenuNode[];
  webPerms?: string;
  apiPerms?: string;
  [k: string]: any;
};

/** 可承载子路由的占位组件（用于父级目录节点） */
const RouterViewHolder = { name: 'RouterViewHolder', render() { return h(_resolve('RouterView')) } };

/** 预加载所有视图组件，供动态菜单按 component 精确匹配加载 */
const viewModules = import.meta.glob('../views/**/*.vue');

/** 将后端菜单节点映射为路由记录（支持根据 node.component 动态加载页面组件） */
export function buildRoutesFromMenus(menus: MenuNode[]): RouteRecordRaw[] {
  const toRoute = (node: MenuNode, parentAbsPath?: string): RouteRecordRaw => {
    // 绝对路径（以 / 开头），无则回退 /{menuId|随机}
    const absPath = normalizePath(node.path, node.menuId);

    // 子路由使用相对段，保证渲染到父级 <router-view />
    const pathForRoute = parentAbsPath
      ? (absPath.startsWith(parentAbsPath + '/') ? absPath.slice(parentAbsPath.length + 1) : absPath.replace(/^\//, ''))
      : absPath;

    const route: RouteRecordRaw = {
      path: pathForRoute,
      name: (node.menuName || 'route') + '-' + node.menuId,
      component: resolveComponent(node.component),
      meta: {
        title: node.menuName,
        perms: normalizePerms(node),
        menuId: node.menuId,
      },
      children: [],
    };
    if (node.children && node.children.length) {
      route.children = node.children.map((child) => toRoute(child, absPath));
    }
    return route;
  };
  return (menus || []).map((m) => toRoute(m));
}

/** 规范路由路径为以 / 开头；无 path 则回退为 /{menuId|随机} */
function normalizePath(p?: string, id?: number): string {
  if (p && typeof p === 'string') {
    return p.startsWith('/') ? p : `/${p}`;
  }
  return '/' + (id ?? Math.random().toString(36).slice(2));
}

/** 根据后端提供的 component 值解析到实际的视图组件（相对 views 目录） */
function resolveComponent(component?: string): any {
  if (!component || typeof component !== 'string') return RouterViewHolder as any;
  const clean = component.replace(/^\/+/, '').replace(/^src\/?/, '').replace(/^views\/?/, '');
  const candidates = [
    `../views/${clean}.vue`,
    `../views/${clean}/index.vue`,
    `../views/${clean}.tsx`,
  ];
  for (const key of candidates) {
    if (key in viewModules) {
      // 懒加载组件
      return viewModules[key] as any;
    }
  }
  console.warn('[dynamic-route] component not found:', component, 'tried:', candidates);
  return RouterViewHolder as any;
}

function normalizePerms(node: MenuNode): string[] | undefined {
  const perms: string[] = [];
  if (node.webPerms && typeof node.webPerms === 'string') perms.push(node.webPerms);
  if (node.apiPerms && typeof node.apiPerms === 'string') perms.push(node.apiPerms);
  return perms.length ? perms : undefined;
}

// 注册动态路由（根级）
export function registerDynamicRoutes(router: any, routes: RouteRecordRaw[]) {
  for (const r of routes) {
    try {
      if (!isRouteRegistered(router, r)) {
        router.addRoute(r);
      }
    } catch {
      // ignore add errors
    }
  }
}

// 注册动态子路由到指定父路由
export function registerDynamicChildren(router: any, parentName: string, routes: RouteRecordRaw[]) {
  for (const r of routes) {
    try {
      if (!isRouteRegistered(router, r)) {
        router.addRoute(parentName, r);
      }
    } catch {
      // ignore add errors
    }
  }
}

function isRouteRegistered(router: any, r: RouteRecordRaw): boolean {
  const name = r.name as string | undefined;
  if (!name) return false;
  return !!router.getRoutes().find((x: any) => x.name === name);
}